<template>
  <div ref="viewScaleRef" class="cjui-view-scale">
    <div
      :class="['cjui-view-scale-wrap', mode !== 'w' && 'is-center']"
      :style="{
        width: `${wrapWidth}px`,
        height: `${wrapHeight}px`,
      }"
    >
      <div
        class="cjui-view-scale-container"
        :style="{
          width: `${dWidth}px`,
          height: `${dHeight}px`,
          minWidth: `${dWidth}px`,
          minHeight: `${dHeight}px`,
          transform: `scale(${scaleX}, ${scaleY})`,
          transformOrigin: mode !== 'w' ? 'center center' : '0 0',
        }"
      >
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, provide, onMounted, onBeforeUnmount } from 'vue'
import { debounceFun } from './helper/debounceFun'

defineOptions({
  name: 'CjuiViewScale',
})

const props = defineProps({
  // 设计图尺寸 - 宽
  dWidth: {
    type: Number,
    default: 1920,
  },
  // 设计图尺寸 - 高
  dHeight: {
    type: Number,
    default: 1080,
  },
  // 伸缩模式 - default(等比缩放) | full(填满容器) | w(以宽度比缩放)
  mode: {
    type: String,
    default: 'default',
  },
})

const viewScaleRef = ref()
const wrapWidth = ref(props.dWidth)
const wrapHeight = ref(props.dHeight)

const scaleX = ref(1)
const scaleY = ref(1)
provide('cjuiViewScaleX', scaleX.value)
provide('cjuiViewScaleY', scaleY.value)

function getScale() {
  const clientWidth = viewScaleRef.value.clientWidth
  const clientHeight = viewScaleRef.value.clientHeight

  scaleX.value = clientWidth / props.dWidth
  scaleY.value = clientHeight / props.dHeight

  if (props.mode === 'full') {
  } else if (props.mode === 'w') {
    scaleY.value = scaleX.value
  } else {
    if (scaleX.value > scaleY.value) {
      scaleX.value = scaleY.value
    } else {
      scaleY.value = scaleX.value
    }
  }

  wrapWidth.value = scaleX.value * props.dWidth
  wrapHeight.value = scaleY.value * props.dHeight
}
const debounceGetScale = debounceFun(getScale)

const ro = new ResizeObserver((_entries) => debounceGetScale())

onMounted(() => {
  getScale()
  ro.observe(viewScaleRef.value)
})

onBeforeUnmount(() => {
  ro.disconnect()
})
</script>

<style lang="scss">
.cjui-view-scale {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: auto;
}

.cjui-view-scale-wrap {
  position: relative;
  overflow: hidden;
  margin: auto;

  &.is-center {
    display: flex;
    justify-content: center;
    align-items: center;
  }
}

.cjui-view-scale-container {
  overflow: auto;
}
</style>
